gdk: Add serializers and deserializers for GFile
authorBenjamin Otte <otte@redhat.com>
Wed, 29 Nov 2017 07:13:06 +0000 (08:13 +0100)
committerBenjamin Otte <otte@redhat.com>
Sun, 3 Dec 2017 04:46:48 +0000 (05:46 +0100)
in particular, support:
GFile <=> text/uri-list
GFile  => text/plain

gdk/gdkcontentdeserializer.c
gdk/gdkcontentserializer.c
tests/testclipboard2.c

index f6a3f6f2bf8d3ac9852448f62eef196245c96151..b9a369f2abca546eccfaa043f9b440aa1333ebdb 100644 (file)
@@ -22,6 +22,7 @@
 #include "gdkcontentdeserializer.h"
 
 #include "gdkcontentformats.h"
+#include "gdkintl.h"
 
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
@@ -523,6 +524,68 @@ string_deserializer (GdkContentDeserializer *deserializer)
   g_object_unref (filter);
 }
 
+static void
+file_uri_deserializer_finish (GObject      *source,
+                              GAsyncResult *result,
+                              gpointer      deserializer)
+{
+  GOutputStream *stream = G_OUTPUT_STREAM (source);
+  GError *error = NULL;
+  gssize written;
+  char *str;
+  char **uris;
+
+  written = g_output_stream_splice_finish (stream, result, &error);
+  if (written < 0)
+    {
+      gdk_content_deserializer_return_error (deserializer, error);
+      return;
+    }
+
+  /* write terminating NULL */
+  if (!g_output_stream_write (stream, "", 1, NULL, &error))
+    {
+      gdk_content_deserializer_return_error (deserializer, error);
+      return;
+    }
+
+  str = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (
+            g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (stream))));
+  uris = g_uri_list_extract_uris (str);
+  g_free (str);
+
+  if (uris == NULL || uris[0] == NULL)
+    {
+      error = g_error_new (G_IO_ERROR, G_IO_ERROR, _("No file given"));
+      gdk_content_deserializer_return_error (deserializer, error);
+    }
+  else
+    {
+      GFile *file = g_file_new_for_uri (uris[0]);
+
+      g_value_take_object (gdk_content_deserializer_get_value (deserializer), file);
+      gdk_content_deserializer_return_success (deserializer);
+    }
+  g_strfreev (uris);
+}
+
+static void
+file_uri_deserializer (GdkContentDeserializer *deserializer)
+{
+  GOutputStream *output;
+
+  output = g_memory_output_stream_new_resizable ();
+
+  g_output_stream_splice_async (output,
+                                gdk_content_deserializer_get_input_stream (deserializer),
+                                G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
+                                gdk_content_deserializer_get_priority (deserializer),
+                                gdk_content_deserializer_get_cancellable (deserializer),
+                                file_uri_deserializer_finish,
+                                deserializer);
+  g_object_unref (output);
+}
+
 static void
 init (void)
 {
@@ -576,6 +639,12 @@ init (void)
 
   g_slist_free (formats);
 
+  gdk_content_register_deserializer ("text/uri-list",
+                                     G_TYPE_FILE,
+                                     file_uri_deserializer,
+                                     NULL,
+                                     NULL);
+
   gdk_content_register_deserializer ("text/plain;charset=utf-8",
                                      G_TYPE_STRING,
                                      string_deserializer,
index 045cd20ce9d906f4331a8eb7fc5bb25593bca3b0..eddc8be64ed987ae181457609742945299680f0e 100644 (file)
@@ -511,6 +511,66 @@ string_serializer (GdkContentSerializer *serializer)
   g_object_unref (filter);
 }
 
+static void
+file_serializer_finish (GObject      *source,
+                        GAsyncResult *result,
+                        gpointer      serializer)
+{
+  GOutputStream *stream = G_OUTPUT_STREAM (source);
+  GError *error = NULL;
+
+  if (!g_output_stream_write_all_finish (stream, result, NULL, &error))
+    gdk_content_serializer_return_error (serializer, error);
+  else
+    gdk_content_serializer_return_success (serializer);
+}
+
+static void
+file_uri_serializer (GdkContentSerializer *serializer)
+{
+  GFile *file;
+  GString *str;
+  char *uri;
+
+  str = g_string_new (NULL);
+
+  file = g_value_get_object (gdk_content_serializer_get_value (serializer));
+  uri = g_file_get_uri (file);
+  g_string_append (str, uri);
+  g_free (uri);
+  g_string_append (str, "\r\n");
+
+  g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer),
+                                   str->str,
+                                   str->len,
+                                   gdk_content_serializer_get_priority (serializer),
+                                   gdk_content_serializer_get_cancellable (serializer),
+                                   file_serializer_finish,
+                                   serializer);
+  gdk_content_serializer_set_task_data (serializer, g_string_free (str, FALSE), g_free);
+}
+
+static void
+file_text_serializer (GdkContentSerializer *serializer)
+{
+  GFile *file;
+  char *path;
+
+  file = g_value_get_object (gdk_content_serializer_get_value (serializer));
+  path = g_file_get_path (file);
+  if (path == NULL)
+    path = g_file_get_uri (file);
+
+  g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer),
+                                   path,
+                                   strlen (path),
+                                   gdk_content_serializer_get_priority (serializer),
+                                   gdk_content_serializer_get_cancellable (serializer),
+                                   file_serializer_finish,
+                                   serializer);
+  gdk_content_serializer_set_task_data (serializer, path, g_free);
+}
+
 static void
 init (void)
 {
@@ -567,6 +627,17 @@ init (void)
 
   g_slist_free (formats);
 
+  gdk_content_register_serializer (G_TYPE_FILE,
+                                   "text/uri-list",
+                                   file_uri_serializer,
+                                   NULL,
+                                   NULL);
+  gdk_content_register_serializer (G_TYPE_FILE,
+                                   "text/plain;charset=utf-8",
+                                   file_text_serializer,
+                                   NULL,
+                                   NULL);
+
   gdk_content_register_serializer (G_TYPE_STRING,
                                    "text/plain;charset=utf-8",
                                    string_serializer,
index ccdc78a796858be503e87c0d90761574cdeb0417..4baabf5f86cc602c07c75f08e4692e46c6cc9c7b 100644 (file)
@@ -263,6 +263,14 @@ get_button_list (GdkClipboard *clipboard,
                        clipboard,
                        "Invalid UTF-8");
 
+  g_value_init (&value, G_TYPE_FILE);
+  g_value_take_object (&value, g_file_new_for_path (g_get_home_dir ()));
+  add_provider_button (box,
+                       gdk_content_provider_new_for_value (&value),
+                       clipboard,
+                       "home directory");
+  g_value_unset (&value);
+
   return box;
 }